package com.bringspring.system.message.util;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bringspring.common.base.UserInfo;
import com.bringspring.common.constant.MsgCode;
import com.bringspring.common.util.JsonUtil;
import com.bringspring.common.util.StringUtils;
import com.bringspring.common.util.UserProvider;
import com.bringspring.system.base.entity.MessageTemplateEntity;
import com.bringspring.system.base.entity.SmsTemplateEntity;
import com.bringspring.system.base.entity.SysConfigEntity;
import com.bringspring.system.base.exception.BaseException;
import com.bringspring.system.base.model.systemconfig.SmsModel;
import com.bringspring.system.base.service.MessageTemplateService;
import com.bringspring.system.base.service.SmsTemplateService;
import com.bringspring.system.base.service.SysConfigService;
import com.bringspring.system.base.util.SmsUtil;
import com.bringspring.system.external.bean.WeComModel;
import com.bringspring.system.external.config.mutil.WxCpConfiguration;
import com.bringspring.system.message.entity.MessageEntity;
import com.bringspring.system.message.entity.MessageReceiveEntity;
import com.bringspring.system.message.entity.SynThirdInfoEntity;
import com.bringspring.system.message.enums.MessageTypeEnum;
import com.bringspring.system.message.model.message.DingTalkModel;
import com.bringspring.system.message.model.message.EmailModel;
import com.bringspring.system.message.model.message.SentMessageForm;
import com.bringspring.system.message.service.MessageService;
import com.bringspring.system.message.service.MessagereceiveService;
import com.bringspring.system.message.service.SynThirdInfoService;
import com.bringspring.system.permission.entity.UserEntity;
import com.bringspring.system.permission.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.text.StringSubstitutor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

import static com.bringspring.system.external.constant.WxCpSysConfigConsts.WECOM_KEY_NAME;

/**
 * 消息实体类
 *
 * @版本： V1.0.0
 * @版权： 股份有限公司
 * @作者： 开发平台组
 * @日期： 2021/4/22 9:06
 */
@Component
@Slf4j
public class SentMessageUtil {

    @Autowired
    private UserService userService;
    @Autowired
    private UserProvider userProvider;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    WxCpConfiguration wxCpConfiguration;
    @Autowired
    private MessageService messageService;
    @Autowired
    private MessagereceiveService messagereceiveService;
    @Autowired
    private SynThirdInfoService synThirdInfoService;

    @Autowired
    private MessageTemplateService messageTemplateService;
    @Autowired
    private SmsTemplateService smsTemplateService;

    /**
     * 发送消息
     *
     * @param sentMessageForm
     */
    public void sendMessage(SentMessageForm sentMessageForm) {
        List<String> toUserIdsList = sentMessageForm.getToUserIds();
        // 模板id
        String templateId = sentMessageForm.getTemplateId();
        // 参数
        Map<String, String> parameterMap = sentMessageForm.getParameterMap();
        int type = sentMessageForm.getType();
        UserInfo userInfo = userProvider.get();
        boolean flag = true;
        if (!(toUserIdsList != null && toUserIdsList.size() > 0)) {
            log.error("接收人员为空");
            flag = false;
        }
        if (StringUtils.isEmpty(templateId)) {
            log.error("模板Id为空");
            flag = false;
        }
        if (flag) {
            // 获取模板详情
            MessageTemplateEntity entity = messageTemplateService.getInfo(templateId);
            //
            if (ObjectUtil.isNull(entity)) {
                entity = new MessageTemplateEntity();
                entity.setTitle(sentMessageForm.getTitle());
                entity.setContent(sentMessageForm.getContent());
                entity.setIsStationLetter(1);
                entity.setIsDingTalk(0);
                entity.setIsEmail(0);
                entity.setIsSms(0);
                entity.setIsWecom(0);
            }
            Set<String> list = new HashSet<>(5);
            list.add(MessageTypeEnum.SysMessage.getCode()); //默认发送站内信
            if (entity != null) {
                // 发送邮件
                if (entity.getIsEmail() == 1) {
                    list.add(MessageTypeEnum.MailMessage.getCode());
                }
                // 发送短信
                if (entity.getIsSms() == 1) {
                    list.add(MessageTypeEnum.SmsMessage.getCode());
                }
                // 发送钉钉消息
                if (entity.getIsDingTalk() == 1) {
                    list.add(MessageTypeEnum.DingMessage.getCode());
                }
                // 发送企业微信消息
                if (entity.getIsWecom() == 1) {
                    list.add(MessageTypeEnum.QyMessage.getCode());
                }
            }
            for (String sendType : list) {
                MessageTypeEnum typeEnum = MessageTypeEnum.getByCode(sendType);
                switch (typeEnum) {
                    case SysMessage:
                        // 站内消息
                        messageService.sentTemplateMessage(toUserIdsList, type, entity, parameterMap, sentMessageForm.getBodyText());
                        break;
                    case SmsMessage:
                        // 发送短信
                        sendSms(toUserIdsList, entity, parameterMap);
                        break;
                    case MailMessage:
                        // 邮件
                        SendMail(toUserIdsList, userInfo, sendType, entity, parameterMap);
                        break;
                    case QyMessage:
                        // 企业微信
                        JSONObject jsonObject = SendQyWebChat(toUserIdsList, userInfo, sendType, entity, parameterMap);
                        if (!(Boolean) jsonObject.get("code")) {
                            log.error("发送企业微信消息失败，错误：" + jsonObject.get("error"));
                        }
                        break;
                    case DingMessage:
                        // 钉钉
                        JSONObject jsonObject1 = SendDingTalk(toUserIdsList, userInfo, sendType, entity, parameterMap);
                        if (!(Boolean) jsonObject1.get("code")) {
                            log.error("发送钉钉微信消息失败，错误：" + jsonObject1.get("error"));
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    }

    /**
     * 发送企业微信消息
     *
     * @param toUserIdsList
     * @param userInfo
     * @param sendType
     * @param entity
     * @param parameterMap
     * @return
     */
    private JSONObject SendQyWebChat(List<String> toUserIdsList, UserInfo userInfo, String sendType, MessageTemplateEntity entity, Map<String, String> parameterMap){
        // 替换参数
        String content = entity.getContent();
        // 替换参数
        if (StringUtils.isNotEmpty(content) && null != parameterMap) {
            StringSubstitutor strSubstitutor = new StringSubstitutor(parameterMap, "{", "}");
            content = strSubstitutor.replace(content);
        }
        String title = entity.getTitle();
        if (StringUtils.isNotEmpty(title) && null != parameterMap) {
            StringSubstitutor strSubstitutor = new StringSubstitutor(parameterMap, "{", "}");
            title = strSubstitutor.replace(title);
        }

        // 获取系统配置
        JSONObject retJson = new JSONObject();
        WeComModel weComModel;
        String defaultAppUrl;
        try {
            SysConfigEntity weComInfo = sysConfigService.getConfigByKeyName(WECOM_KEY_NAME);
            defaultAppUrl = sysConfigService.getSystemAddress("app");
            if (ObjectUtil.isNotEmpty(weComInfo) && StringUtils.isNotEmpty(weComInfo.getKeyValue())) {
                String keyValue = weComInfo.getKeyValue();
                List<WeComModel> listModel = JsonUtil.getJsonToList(keyValue, WeComModel.class);
                if (CollectionUtil.isNotEmpty(listModel)) {
                    weComModel = listModel.get(0);
                } else {
                    retJson.put("code", false);
                    retJson.put("error", "发送失败：weCom配置企业为空");
                    return retJson;
                }
            } else {
                retJson.put("code", false);
                retJson.put("error", "发送失败：weCom配置不存在");
                return retJson;
            }
        } catch (BaseException e) {
            e.printStackTrace();
            retJson.put("code", false);
            retJson.put("error", "发送失败" + e.getMessage());
            return retJson;
        }

        String corpId = weComModel.getQyhCorpId();
        String agentId = weComModel.getQyhAgentId();
        Boolean isLinkedCorp = weComModel.getIsLinkedCorp();
        // 获取的应用的Secret值
        String corpSecret = weComModel.getQyhAgentSecret();
        String wxUserId = "";
        StringBuilder toWxUserId = new StringBuilder();
        String toUserIdAll = "";
        StringBuilder nullUserInfo = new StringBuilder();
        List<MessageReceiveEntity> messageReceiveList = new ArrayList<>();

        // 相关参数验证
        if (StringUtils.isEmpty(corpId)) {
            log.error("企业ID为空");
        }
        if (StringUtils.isEmpty(corpSecret)) {
            retJson.put("code", false);
            retJson.put("error", "Secret为空");
            return retJson;
        }
        if (StringUtils.isEmpty(agentId)) {
            retJson.put("code", false);
            retJson.put("error", "AgentId为空");
            return retJson;
        }
        if (StringUtils.isEmpty(content)) {
            retJson.put("code", false);
            retJson.put("error", "内容为空");
            return retJson;
        }
        if (toUserIdsList == null || toUserIdsList.size() < 1) {
            retJson.put("code", false);
            retJson.put("error", "接收人为空");
            return retJson;
        }

        // 创建消息实体
        MessageEntity messageEntity = JsbosMessageUtil.setMessageEntity(userInfo.getUserId(), title, content, Integer.parseInt(sendType));

        // 获取接收人员的企业微信号、创建消息用户实体
        for (String userId : toUserIdsList) {
            wxUserId = "";
            // 从同步表获取对应的企业微信ID
//            SynThirdInfoEntity synThirdInfoEntity = synThirdInfoService.getInfoBySysObjId(SynThirdConsts.THIRD_TYPE_QY, SynThirdConsts.DATA_TYPE_USER, userId);
            List<SynThirdInfoEntity> infoBySysObjIds =
                    synThirdInfoService.getInfoBySysObjIds(SynThirdConsts.THIRD_TYPE_QY, SynThirdConsts.DATA_TYPE_USER, userId);
            if (CollectionUtil.isNotEmpty(infoBySysObjIds)) {
                for (int i = 0; i < infoBySysObjIds.size(); i++) {
                    SynThirdInfoEntity synThirdInfoEntity = infoBySysObjIds.get(i);
                    if (synThirdInfoEntity != null) {
                        wxUserId = synThirdInfoEntity.getThirdObjectId();
                    }
                    if (StringUtils.isEmpty(wxUserId)) {
                        nullUserInfo = nullUserInfo.append(",").append(userId);
                    }
                    //互联企业发送使用逗号隔开
                    if(isLinkedCorp){
                        toWxUserId = toWxUserId.append(",").append(wxUserId);
                    }else{
                        toWxUserId = toWxUserId.append("|").append(wxUserId);
                    }
                }
                messageReceiveList.add(JsbosMessageUtil.setMessageReceiveEntity(messageEntity.getId(), userId));
            }
        }

        // 处理企业微信号信息串并验证
        toUserIdAll = toWxUserId.toString();
        if (StringUtils.isNotEmpty(toUserIdAll)) {
            toUserIdAll = toUserIdAll.substring(1);
        }
        if (StringUtils.isEmpty(toUserIdAll)) {
            retJson.put("code", false);
            retJson.put("error", "接收人对应的企业微信号全部为空");
            return retJson;
        }
        String appUrl = parameterMap.get("AppUrl");
        //如果没有传appUrl参数，使用系统配置的移动端地址
        if (StringUtils.isEmpty(appUrl)) {
            appUrl = defaultAppUrl;
        }
        // 批量发送企业信息信息
        if(isLinkedCorp){
            String[] toUserIdArr = toUserIdAll.split(",");
            retJson = QyWebChatUtil.sendLinkWxMessage(corpId, corpSecret, agentId, toUserIdArr, title, content, appUrl);
        }else{
            retJson = QyWebChatUtil.sendWxMessage(corpId, corpSecret, agentId, toUserIdAll, title, content, appUrl);
        }
        if (!retJson.getBoolean("code")) {
            return retJson;
        }

        // 企业微信号为空的信息写入备注
        if (StringUtils.isNotEmpty(nullUserInfo.toString())) {
            messageEntity.setDescription(nullUserInfo.substring(1) + "对应的企业微信号为空");
        }
        // 写入系统的消息表、消息用户表

        retJson.put("code", true);
        retJson.put("error", MsgCode.SU012.get());
        return retJson;
    }

    /**
     * List<String> toUserIdsList, UserInfo userInfo, String sendType, MessageTemplateEntity entity, Map<String, String> parameterMap
     *
     * @param toUserIdsList
     * @param userInfo
     * @param sendType
     * @param entity
     * @param parameterMap
     * @return
     */
    private JSONObject SendDingTalk(List<String> toUserIdsList, UserInfo userInfo, String sendType, MessageTemplateEntity entity, Map<String, String> parameterMap) {
        String content = entity.getContent();

        // 替换参数
        if (StringUtils.isNotEmpty(content)) {
            StringSubstitutor strSubstitutor = new StringSubstitutor(parameterMap, "{", "}");
            content = strSubstitutor.replace(content);
        }

        Map<String, String> objModel = getSystemConfig();
        DingTalkModel dingTalkModel = JsonUtil.getJsonToBean(objModel, DingTalkModel.class);
        String appKey = "dingqgbtl0pzm45qbonu";
        String appSecret = "299RRMGBuD-Hsw9LE76DzJi-ApKmq3MABXm-tS8-plFFt189RrSJi_qB0U7tAot1";
        String agentId = "2798100981";
        String dingUserId = "";
        StringBuilder toDingUserId = new StringBuilder();
        String toUserIdAll = "";
        StringBuilder nullUserInfo = new StringBuilder();
        List<MessageReceiveEntity> messageReceiveList = new ArrayList<>();
        JSONObject retJson = new JSONObject();

        // 相关参数验证
        if (StringUtils.isEmpty(appKey)) {
            retJson.put("code", false);
            retJson.put("error", "AppKey为空");
            return retJson;
        }
        if (StringUtils.isEmpty(appSecret)) {
            retJson.put("code", false);
            retJson.put("error", "AppSecret为空");
            return retJson;
        }
        if (StringUtils.isEmpty(agentId)) {
            retJson.put("code", false);
            retJson.put("error", "AgentId为空");
            return retJson;
        }
        if (StringUtils.isEmpty(content)) {
            retJson.put("code", false);
            retJson.put("error", "内容为空");
            return retJson;
        }
        if (toUserIdsList == null || toUserIdsList.size() < 1) {
            retJson.put("code", false);
            retJson.put("error", "接收人为空");
            return retJson;
        }

        // 创建消息实体
        MessageEntity messageEntity = JsbosMessageUtil.setMessageEntity(userInfo.getUserId(), content, null, Integer.parseInt(sendType));

        // 获取接收人员的钉钉号、创建消息用户实体
        for (String userId : toUserIdsList) {
            dingUserId = "";
            // 从同步表获取对应用户的钉钉ID
            SynThirdInfoEntity synThirdInfoEntity = synThirdInfoService.getInfoBySysObjId(SynThirdConsts.THIRD_TYPE_DING, SynThirdConsts.DATA_TYPE_USER, userId);
            if (synThirdInfoEntity != null) {
                dingUserId = synThirdInfoEntity.getThirdObjectId();
            }
            if (StringUtils.isEmpty(dingUserId)) {
                nullUserInfo = nullUserInfo.append(",").append(userId);
            } else {
                toDingUserId = toDingUserId.append(",").append(dingUserId);
            }
            messageReceiveList.add(JsbosMessageUtil.setMessageReceiveEntity(messageEntity.getId(), userId));
        }

        // 处理接收人员的钉钉号信息串并验证
        toUserIdAll = toDingUserId.toString();
        if (StringUtils.isNotEmpty(toUserIdAll)) {
            toUserIdAll = toUserIdAll.substring(1);
        }
        if (StringUtils.isEmpty(toUserIdAll)) {
            retJson.put("code", false);
            retJson.put("error", "接收人对应的钉钉号全部为空");
            return retJson;
        }

        // 批量发送钉钉信息
        retJson = DingTalkUtil.sendDingMessage(appKey, appSecret, agentId, toUserIdAll, content, parameterMap.get("title"));
        if (!retJson.getBoolean("code")) {
            return retJson;
        }

        // 钉钉号为空的信息写入备注
        if (StringUtils.isNotEmpty(nullUserInfo.toString())) {
            messageEntity.setDescription(nullUserInfo.toString().substring(1) + "对应的钉钉号为空");
        }
        // 写入系统的消息表、消息用户表

        retJson.put("code", true);
        retJson.put("error", MsgCode.SU012.get());
        return retJson;
    }

    /**
     * 发送邮件
     *
     * @param toUserIdsList
     * @param userInfo
     * @param sendType
     * @param entity
     * @param parameterMap
     * @return
     */
    private void SendMail(List<String> toUserIdsList, UserInfo userInfo, String sendType, MessageTemplateEntity entity, Map<String, String> parameterMap) {
        // 获取系统配置
        Map<String, String> objModel = getSystemConfig();

        EmailModel emailModel = JsonUtil.getJsonToBean(objModel, EmailModel.class);
        StringBuilder nullUserInfo = new StringBuilder();
        List<MessageReceiveEntity> messageReceiveList = new ArrayList<>();
        StringBuilder toUserMail = new StringBuilder();
        String userEmailAll = "";
        String userEmail = "";
        String userName = "";

        // 相关参数验证
        if (StringUtils.isEmpty(emailModel.getEmailSmtpHost())) {
            log.error("SMTP服务为空");
        } else if (StringUtils.isEmpty(emailModel.getEmailSmtpPort())) {
            log.error("SMTP端口为空");
        } else if (StringUtils.isEmpty(emailModel.getEmailAccount())) {
            log.error("发件人邮箱为空");
        } else if (StringUtils.isEmpty(emailModel.getEmailPassword())) {
            log.error("发件人密码为空");
        } else if (toUserIdsList == null || toUserIdsList.size() < 1) {
            log.error("接收人为空");
        } else {
            // 设置邮件标题
            emailModel.setEmailTitle(entity.getTitle());
            // 设置邮件内容
            String content = entity.getContent();
            if (StringUtils.isNotEmpty(content)) {
                StringSubstitutor strSubstitutor = new StringSubstitutor(parameterMap, "{", "}");
                content = strSubstitutor.replace(content);
            }
            emailModel.setEmailContent(content);

            // 创建消息实体
            MessageEntity messageEntity = JsbosMessageUtil.setMessageEntity(userInfo.getUserId(), emailModel.getEmailTitle(), emailModel.getEmailContent(), Integer.parseInt(sendType));

            // 获取收件人的邮箱地址、创建消息用户实体
            for (String userId : toUserIdsList) {
                UserEntity userEntity = userService.getInfo(userId);
                if (userEntity != null) {
                    userEmail = StringUtils.isEmpty(userEntity.getEmail()) ? "" : userEntity.getEmail();
                    userName = userEntity.getRealName();
                }
                if (userEmail != null && !"".equals(userEmail)) {
                    toUserMail = toUserMail.append(",").append(userName).append("<").append(userEmail).append(">");
                } else {
                    nullUserInfo = nullUserInfo.append(",").append(userId);
                }
                messageReceiveList.add(JsbosMessageUtil.setMessageReceiveEntity(messageEntity.getId(), userId));
            }

            // 处理接收人员的邮箱信息串并验证
            userEmailAll = toUserMail.toString();
            if (StringUtils.isNotEmpty(userEmailAll)) {
                userEmailAll = userEmailAll.substring(1);
            }
            if (StringUtils.isEmpty(userEmailAll)) {
                log.error("接收人对应的邮箱全部为空");
            } else {
                // 设置接收人员
                emailModel.setEmailToUsers(userEmailAll);
                // 发送邮件
                JSONObject retJson = EmailUtil.sendMail(emailModel);
                if (!retJson.getBoolean("code")) {
                    log.error("发送失败");
                } else {
                    // 邮箱地址为空的信息写入备注
                    if (StringUtils.isNotEmpty(nullUserInfo.toString())) {
                        messageEntity.setDescription(nullUserInfo.substring(1) + "对应的邮箱为空");
                    }
                    // 写入系统的消息表、消息用户表
                }
            }
        }
    }

    /**
     * 发送短信
     *
     * @param toUserIdsList
     * @param entity
     * @param parameterMap
     * @return
     */
    private void sendSms(List<String> toUserIdsList, MessageTemplateEntity entity, Map<String, String> parameterMap) {
        // 组装接受用户
        StringBuffer toUserIdList = new StringBuffer();
        for (String toUserId : toUserIdsList) {
            UserEntity userEntity = userService.getInfo(toUserId);
            toUserIdList.append(userEntity.getMobilePhone() + ",");
        }

        if (entity != null && entity.getIsSms() == 1) {
            SmsModel smsConfig = smsTemplateService.getSmsConfig();
            // 获取短信模板id
            String smsId = entity.getSmsId();
            SmsTemplateEntity smsTemplateEntity = smsTemplateService.getInfo(smsId);
            if (smsTemplateEntity != null) {
                // 发送短信
                SmsUtil.sentSms(smsTemplateEntity.getCompany(), smsConfig, smsTemplateEntity.getEndpoint(), smsTemplateEntity.getRegion(), toUserIdList.toString(), smsTemplateEntity.getSignContent(), smsTemplateEntity.getTemplateId(), parameterMap);
            }
        }
    }

    /**
     * 获取系统配置
     */
    private Map<String, String> getSystemConfig() {
        // 获取系统配置
        List<SysConfigEntity> configList = sysConfigService.getList();
        Map<String, String> objModel = new HashMap<>(16);
        for (SysConfigEntity entity : configList) {
            objModel.put(entity.getKeyName(), entity.getKeyValue());
        }
        return objModel;
    }

}
